package presstrack
{
	/**
	 * TODO:
	 * убрать всю логику из updateParam, 
	 * оставить только вызов метода на сервере
	 * и вызов resFunc.
	 * все остальное - обработку результата - 
	 * перенести в методы set
	 * 
	 * еще лучше - реализовать патерн Composite
	 * куда вынести updateParam
	 * */	
	import flash.net.Responder;
	
	import mx.utils.ObjectUtil;
	
	import org.presstrack.service.*;
	import org.presstrack.vos.TrackStateVO;
	
	[RemoteClass(alias="presstrack.OrderClass")]
	
	[Bindable]
	public class OrderClass
	{
		public var iOrderId:int;
  		public var iLabel:int;
  		public var mCreationDate:String;
  		public var mExpiryDate:String;
  		public var iManagerId:int;	
  		public var mManagerName:String;
  		public var iCustomerId:int;
  		public var mCustomerName:String;
  		public var dPrice:String;
  		public var dDebt:String;
  		public var mNote:String;
  		public var mProductName:String;
  		public var iGroupNum:int;
  		public var arGroup:Array;
  		  		
  		public var iState:int;
  		
  		public var iStatePaper:int;
		public var iStatePrepress:int;
		public var iStatePress:int;
		public var iStatePostpress:int;
		public var iStateDestination:int;
	
  		public var statePaper:TrackStateVO;
  		public var statePrepress:TrackStateVO;
  		public var statePress:TrackStateVO;
  		public var statePostpress:TrackStateVO;
  		public var stateDestination:TrackStateVO;  				
				
		public function OrderClass(order:Object = null)
		{
			if (order != null ) setFrom(order);			 
		}
		
		public function setFrom(ob:Object):Boolean
		{
			if (ob == null) return false;
			
			if (ob.hasOwnProperty("iOrderId"))
				iOrderId = Number(ob.iOrderId);
				
			if (ob.hasOwnProperty("iLabel"))
				iLabel = Number(ob.iLabel);
				
			if (ob.hasOwnProperty("arGroup")) {
				arGroup = new Array();
				for each(var g:Object in ob.arGroup) {
					var p:OrderPartClass = new OrderPartClass(g);
					arGroup.push(p);
				}
				
				mProductName = "";
				for each (var part:OrderPartClass in arGroup) {
					for each (var pr:ProductClass in part.products)
						mProductName += pr.label + ", " + pr.run + " шт. \r";
				}
			}
				
			if (ob.hasOwnProperty("mNote"))
				if (ob.mNote != null) mNote = ob.mNote.toString();
				
			if (ob.hasOwnProperty("mExpiryDate"))
				mExpiryDate = ob.mExpiryDate.toString();
				
			if (ob.hasOwnProperty("mManagerName"))
				mManagerName = ob.mManagerName.toString();
				
			if (ob.hasOwnProperty("mCustomerName"))
				mCustomerName = ob.mCustomerName.toString();
				
			if (ob.hasOwnProperty("iManagerId"))
				iManagerId = Number(ob.iManagerId);
				
			if (ob.hasOwnProperty("iCustomerId"))
				iCustomerId = Number(ob.iCustomerId);
				
			if (ob.hasOwnProperty("mCreationDate"))
				mCreationDate = ob.mCreationDate.toString();
				
			if (ob.hasOwnProperty("dPrice"))
				dPrice = Number(ob.dPrice).toFixed(2);
				
			if (ob.hasOwnProperty("dDebt"))
				dDebt = Number(ob.dDebt).toFixed(2);
				
			if (ob.hasOwnProperty("iGroupNum"))
				iGroupNum = Number(ob.iGroupNum);
				
			if (ob.hasOwnProperty("iState")) 
				iState = Number(ob.iState);
				
			if (ob.hasOwnProperty("iStatePaper")) 
				statePaper = new TrackStateVO(ob.iStatePaper.toString());
		
			if (ob.hasOwnProperty("iStatePrepress"))
				statePrepress = new TrackStateVO(ob.iStatePrepress.toString());
				
			if (ob.hasOwnProperty("iStatePress"))
				statePress = new TrackStateVO(ob.iStatePress.toString());
				
			if (ob.hasOwnProperty("iStatePostpress"))
				statePostpress = new TrackStateVO(ob.iStatePostpress.toString());
				
			if (ob.hasOwnProperty("iStateDestination"))
				stateDestination = new TrackStateVO(ob.iStateDestination.toString());
					
			return true;
		}
		
		public function updatePrice():void 
		{
			var pr:Number = new Number();
			for each (var p:OrderPartClass in arGroup) {
				for each (var t:TaskClass in p.tasks) 
					pr += Number(t.cost);
			}
			dPrice = pr.toFixed(2);
		}
		
		public function generateLabel(resFunc	:Function	= null, 
									  faultFunc	:Function	= null):void 
		{
			CrudService.crud.srv.call("PressTrack.GenerateLabelForOrder", new Responder(onRes));
			
			function onRes(res:int):void 
			{
				setLabel(res.toString(), resFunc, faultFunc);
			}			
		}
		
		public function setLabel(value		:String, 
								 resFunc	:Function	= null, 
								 faultFunc	:Function	= null):void
		{
			updateParam("label", value, onRes, faultFunc);
			
			function onRes():void 
			{
				iLabel = int(value);
				if (resFunc != null)
				{
					resFunc();
				}
			}
		}
		
		public function setExpiry(value:String, resFunc:Function = null, faultFunc:Function = null):void
		{
			updateParam("expiry", value, onRes, faultFunc);
			
			function onRes():void {
				mExpiryDate = value;
				if (resFunc != null)
				{
					resFunc();
				}
			}
		}
		
		public function setCustomer(value:String, resFunc:Function = null, faultFunc:Function = null):void
		{
			updateParam("customer", value, onRes, faultFunc);
			
			function onRes():void {
				iCustomerId = int(value);
					
				for each(var cust:CustomerClass in CrudService.arCustomer) {
					if (cust.iUserId == iCustomerId) {
						mCustomerName = cust.mName;
						break;
					}
				}
					
				if (resFunc != null)
				{
					resFunc();
				}
			}
		}
		
		public function setNote(value:String, resFunc:Function = null, faultFunc:Function = null):void
		{
			updateParam("note", value, onRes, faultFunc);
			
			function onRes():void {
				mNote = value;
				if (resFunc != null)
				{
					resFunc();
				}
			}
		}
		
		public function addPart(resFunc:Function = null, faultFunc:Function = null):void 
		{
			CrudService.crud.srv.call("PressTrack.AddGroup", new Responder(onResult, onFault), iOrderId);
			
			function onResult(result:Object):void 
			{
				if (result.status == true)
				{
					var p:OrderPartClass = new OrderPartClass(result.part);
					arGroup.push(p);	
					++iGroupNum;
					if (resFunc != null) resFunc();				
				}
				else
					faultFunc(result.message);				
			}
			
			function onFault(e:Object) : void {
				faultFunc(ObjectUtil.toString(e));
			}
		}
		
		public function deletePart(part:int, resFunc:Function = null, faultFunc:Function = null ) : void 
		{
			CrudService.crud.srv.call("PressTrack.RemoveGroup",  new Responder(onResult, onFault), iOrderId, part);
			
			function onResult(res:String) : void 
			{
				if (res == 'successful') 
				{
					var ind:int = CrudService.arCurOrder.getItemIndex(this);
					CrudService.crud.getOrder(iOrderId, ind, resFunc);
				}
				else	
					faultFunc(res);	
			}
			
			function onFault(e:Object) : void {
				faultFunc(ObjectUtil.toString(e));
			}
		}
		
		public function setState(value:String, resFunc:Function = null, faultFunc:Function = null):void
		{
			updateParam("state", value, onRes, faultFunc);
			
			function onRes():void 
			{
				iState = int(value);
				if (resFunc != null)
				{
					resFunc();
				}
			}
		}
		
		public function calculate(resFunc	:Function	= null, 
								  faultFunc	:Function	= null):void 
		{
			CrudService.crud.srv.call("PressTrack.CalculateCostOfOrder", new Responder(onResult), iOrderId);
			
			function onResult(result:Object):void 
			{
				if (result.bStatus == true)
				{
					var pr:Number = new Number();
					for each (var ob:Object in result.arTask) 
					{
						for each (var p:OrderPartClass in arGroup) 
						{
							for each (var t:TaskClass in p.tasks) 
							{
								if (t.idtask == ob.idtask) 
								{
									t.cost = ob.cost;
									pr += Number(t.cost);
									break;
								}
							}
						}
					}
					dPrice = pr.toFixed(2);
					if (resFunc != null)
					{
						resFunc();
					}
				}
				else if (faultFunc != null)
				{
					faultFunc(result.mMessage);
				}
			}
		}
		
		public function addPayment(payment		:PaymentClass, 
								   resFunc		:Function		= null, 
								   faultFunc	:Function		= null):void 
		{
			CrudService.crud.srv.call("PressTrack.AddPayment", new Responder(onResult, onFault), 
									 iOrderId, payment.mCreationDate, payment.mAccount, payment.dSum, payment.mNote);	
			
			function onResult(idpayment:String):void 
			{
				if (Number(idpayment)) 
				{
					payment.iPaymentId = Number(idpayment);
					CrudService.arPayment.addItemAt(payment, 0);
					CrudService.arPayment.refresh();	
					
					dDebt = (Number(dDebt) - payment.dSum).toFixed(2);
					
					if (resFunc != null)
					{
						resFunc();
					}
															
					for each(var cust:PayerClass in CrudService.arCustomer) 
					{
						if (cust.iUserId == iCustomerId) 
						{
							cust.obStatistic.dDebt -= payment.dSum;
							CrudService.arCustomer.refresh();
							break;
						}												
					}					
				}
				else
				{
					faultFunc(idpayment);
				}
			}
			
			function onFault(e:Object) : void {
				faultFunc(ObjectUtil.toString(e));
			}		
		}
		
		public function copyOrder(resFunc	:Function	= null, 
								  faultFunc	:Function	= null):void 
		{
			CrudService.crud.srv.call("PressTrack.CopyOrder", new Responder(onResult, onFault), iOrderId);
			
			function onResult( result:Object ):void {
				if (result.status == true)
				{
					var order:OrderClass = new OrderClass(result.order);
					CrudService.arCurOrder.addItem(order);
					CrudService.arCurOrder.refresh();
					CrudService.curOrder = CrudService.arCurOrder[CrudService.arCurOrder.length - 1];
					if (resFunc != null) resFunc();
				}
				else
					faultFunc(result.message);
			}
			
			function onFault(e:Object) : void {
				faultFunc(ObjectUtil.toString(e));
			}
		}
		
		// private
		
		private function updateParam(param:String, value:String, resFunc:Function = null, faultFunc:Function = null):void 
		{
			CrudService.crud.srv.call("PressTrack.UpdateOrder", new Responder(onResult, onFault), iOrderId, param, value);
			
			function onResult(res:String) : void 
			{
				if (res == 'successful') 
				{
					if (param == "state") 
					{						
						if (value == "4") {
							CrudService.arStoreOrder.addItem( CrudService.curOrder );
							CrudService.arCurOrder.removeItemAt( CrudService.arCurOrder.getItemIndex(CrudService.curOrder) );
							CrudService.arCurOrder.refresh();	
							CrudService.arStoreOrder.refresh();	
							CrudService.curOrder = new OrderClass;				
						}
						else if (value == "9") {
							statePaper = new TrackStateVO("6");
							statePrepress = new TrackStateVO("6");
							statePress = new TrackStateVO("6");
							statePostpress = new TrackStateVO("6");
							stateDestination = new TrackStateVO("6");
						}
						else if (value == "1") {
							statePaper = new TrackStateVO("1");
							statePrepress = new TrackStateVO("1");
							statePress = new TrackStateVO("1");
							statePostpress = new TrackStateVO("1");
							stateDestination = new TrackStateVO("1");
						}		
					}
					
					if(resFunc != null)
					{
						resFunc();
					}					
				}					
				else
				{
					if(faultFunc != null)
					{
						faultFunc(res);
					}	
				}			
			}
			
			function onFault(e:Object) : void {
				faultFunc(ObjectUtil.toString(e));
			}			
		}		
	}	
}